package cn.nfwx.tv.widget.seekbar;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.SeekBar;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.List;

import cn.nfwx.tv.R;
import cn.nfwx.tv.util.LogUtil;
import cn.nfwx.tv.util.TimeUtil;

/**
 * 节目点击
 * Created by zhouzechao on 2018/1/9.
 */
public class PointSeekBar extends android.support.v7.widget.AppCompatSeekBar {

    ArrayList<Point> mPoints = new ArrayList<Point>();
    private static final int W_P = 30;
    private PointSeekBarListener pointSeekBarListener;

    // ====弹框 ====
    private WindowManager mWindowManager;
    private BubbleView mBubbleView;
    private WindowManager.LayoutParams mLayoutParams;
    private float bubbleWidth;
    private float bubbleHeight;
    private float top; // 所有夫级view的getTop相加

    public PointSeekBarListener getPointSeekBarListener() {
        return pointSeekBarListener;
    }

    public void setPointSeekBarListener(PointSeekBarListener pointSeekBarListener) {
        this.pointSeekBarListener = pointSeekBarListener;
    }

    public interface PointSeekBarListener {
        void seekToPoint(Point point);
    }

    public PointSeekBar(Context context) {
        super(context);

        init(context);
    }

    public PointSeekBar(Context context, AttributeSet attrs) {
        super(context, attrs);

        init(context);
    }

    public PointSeekBar(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        init(context);
    }

    @Override
    protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    Drawable mThumb;

    @Override
    public void setThumb(Drawable thumb) {
        super.setThumb(thumb);
        mThumb = thumb;
    }

    // 4.0.4的报错修复
    public Drawable getSeekBarThumb() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            return getThumb();
        }
        return mThumb;
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);

        if (getSeekBarThumb() != null) {
            synchronized (mPoints) {
                for (Point point : mPoints) {
                    loadPointData(point);
                }
            }
            // 才用递归方式获取控件离屏幕的高度
            if (top == 0) {
                if (PointUtil.isMIUI() || Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
                    top = getTop(this) - 50;
                } else {
                    int[] location = new int[2];
                    getLocationOnScreen(location);
                    int y = location[1];
                    top = y - bubbleHeight;
                }
            }
        }
    }

    @Override
    protected synchronized void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        drawPoints(canvas);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        return super.dispatchTouchEvent(event);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                float x = event.getX();
                // 时移模块
                Drawable thumb = getSeekBarThumb();
                if (thumb == null) {
                    return false;
                } else {
                    Rect rect = new Rect();
                    thumb.copyBounds(rect);
                    if (x >= rect.left - 5 && x <= rect.right + 5) {
                        return super.onTouchEvent(event);
                    } else {
                        // 节目模块
                        synchronized (mPoints) {
                            for (Point point : mPoints) {
                                if (point.getOffsetLeft() - 5 <= x && point.getOffsetRight() + 5 >= x) {
                                    showBubble(point, getLeft() + (point.getOffsetLeft() + point.getOffsetRight()) / 2, top);
                                    break;
                                }
                            }
                        }
                        return false;
                    }
                }
        }
        return super.onTouchEvent(event);
    }

    /**
     * 画点
     *
     * @param canvas
     */
    private void drawPoints(Canvas canvas) {
        if (getSeekBarThumb() != null) {
            Paint paint = new Paint();
            paint.setColor(Color.WHITE);
            synchronized (mPoints) {
                List<Point> points = new ArrayList<>();
                points.addAll(mPoints);
                for (Point point : points) {
                    loadPointData(point);
                    Rect rect = new Rect();
                    getProgressDrawable().copyBounds(rect);
                    RectF positionRect = new RectF(point.getOffsetLeft(), rect.top, point.getOffsetRight(), rect.bottom);
                    canvas.drawRoundRect(positionRect, 5, 5, paint);
                }
            }
        }
    }

    /**
     * 初始化点位置
     *
     * @param context
     */
    private void init(Context context) {
        mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        mBubbleView = new BubbleView(context);

        bubbleWidth = getResources().getDimension(R.dimen.bubble_width);
        bubbleHeight = getResources().getDimension(R.dimen.bubble_height);

        mLayoutParams = new WindowManager.LayoutParams();
        mLayoutParams.gravity = Gravity.START | Gravity.TOP;
        mLayoutParams.width = ViewGroup.LayoutParams.WRAP_CONTENT;
        mLayoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;
        mLayoutParams.format = PixelFormat.TRANSLUCENT;
        mLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;

        // MIUI禁止了开发者使用TYPE_TOAST，Android 7.1.1 对TYPE_TOAST的使用更严格
        if (PointUtil.isMIUI() || Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
            mLayoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION;
        } else {
            mLayoutParams.type = WindowManager.LayoutParams.TYPE_TOAST;
        }
    }

    /**
     * 递归方法获取所有gettop
     *
     * @param view
     * @return
     */
    private int getTop(View view) {
        int top = view.getTop();
        if (view.getParent() instanceof ViewGroup) {
            ViewGroup viewGroup = (ViewGroup) view.getParent();
            if (viewGroup == null) {
                return top;
            } else {
                return top + getTop(viewGroup);
            }
        }
        return top;
    }

    public void initData() {
        ArrayList<Point> p = new ArrayList<>();
        p.add(new Point(0));
        p.add(new Point(10));
        p.add(new Point(50));
        p.add(new Point(70));
        p.add(new Point(100));
        setPoints(p);
    }

    public void clearData() {
        //LogUtil.e("ttt","clearData");
        mPoints.clear();
        postInvalidate();
    }

    /**
     * 设置点
     *
     * @param points
     */
    public void setPoints(List<Point> points) {
        if (points != null) {
            mPoints.clear();
            mPoints.addAll(points);
            postInvalidate();
        }
    }

    /**
     * 初始化各个点对应位置
     *
     * @param point
     */
    private void loadPointData(Point point) {
        if (point.getPosition() > getMax()) {
            return;
        }
        Rect rect = new Rect();
        getProgressDrawable().copyBounds(rect);
        int width = getWidth(); // 控件宽度
        // 计算模块对应的位置
        int poistionOffset = (int) (rect.width() * (point.getPosition() * 1F / 100)) + (width - rect.width()) / 3;
        //LogUtil.e("ttt", point.getPosition() + "---" + getMax() + "---" + width + "---" + rect.left + "----" + rect.right + "----" + rect.width());
        point.setOffsetLeft(poistionOffset);
        point.setOffsetRight(poistionOffset + W_P);
    }

    /**
     * 显示气泡
     *
     * @param point
     * @param rawX
     * @param rawY
     */
    private void showBubble(Point point, float rawX, float rawY) {
        if (point == null) {
            return;
        }
        if (mBubbleView == null) {
            return;
        }
        if (mBubbleView.getParent() != null) {
            hideBubble();
        }
        mLayoutParams.x = (int) (rawX - bubbleWidth / 2 + 15);
        mLayoutParams.y = (int) (rawY - bubbleHeight);

        mWindowManager.addView(mBubbleView, mLayoutParams);
        mBubbleView.setVisibility(VISIBLE);

        mBubbleView.setPoint(point);
    }

    /**
     * 隐藏气泡
     */
    public void hideBubble() {
        if (mBubbleView == null)
            return;

        mBubbleView.setVisibility(GONE); // 防闪烁
        if (mBubbleView.getParent() != null) {
            mWindowManager.removeViewImmediate(mBubbleView);
        }
    }

    /**
     * 弹框模块
     */
    private class BubbleView extends LinearLayout implements OnClickListener {

        private TextView program_time;
        private TextView program_name;
        //        private ImageView iv_program_seek;
        private Point point;

        BubbleView(Context context) {
            this(context, null);
        }

        BubbleView(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }

        BubbleView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);

            LayoutInflater.from(context).inflate(R.layout.view_bubble, this, true);
            program_time = findViewById(R.id.program_time);
            program_name = findViewById(R.id.program_name);
//            iv_program_seek = findViewById(R.id.iv_program_seek);

            setOnClickListener(this);
        }

        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        }

        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);

        }

        public void setPoint(Point point) {
            this.point = point;

            loadData();
        }

        private void loadData() {
            program_name.setText(point.getText());
            if (point.getTime() <= 0) {
                program_time.setText("00:00:00");
            } else {
                program_time.setText(TimeUtil.getTodayTime(point.getTime()));
            }
        }

        @Override
        public void onClick(View v) {
            if (pointSeekBarListener != null) {
                pointSeekBarListener.seekToPoint(point);
            }
        }
    }


}
